﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO;
using Microsoft.Win32;
using PropertyCreator.Models;
using System.Linq;
using System.Diagnostics;
using System.Threading;
using PropertyCreator.Core;

namespace PropertyCreator
{
    public partial class MainFrm : Form
    {
        static DbServer DbSvr = null;
        readonly string folder = "Output";
        private bool initDb = false;    //是否初始化了数据库
        private TextBoxWriter textBoxWriter;

        public MainFrm()
        {
            InitializeComponent();
        }

        private void MainFrm_Load(object sender, EventArgs e)
        {
            //选择注册表
            combFromRegister.Items.Add("不从注册表加载");
            foreach (string item in Code.GetRegisterNameList())
            {
                combFromRegister.Items.Add(item);
            }

            //初始化输出目录
            txtOutPut.Text = string.Format(@"{0}\{1}\{2}", Application.StartupPath, folder, DateTime.Now.ToString("yyyyMMdd"));
            if (Directory.Exists(txtOutPut.Text) == false)
            {
                //不存在目录则创建出来
                Directory.CreateDirectory(txtOutPut.Text);
            }

            //控制流回写
            textBoxWriter = new TextBoxWriter(txtLog);
            Console.SetOut(textBoxWriter);
        }

        /// <summary>
        /// 测试连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnTestConn_Click(object sender, EventArgs e)
        {
            DbSvr = new DbServer(this.combServerAddress.Text,
                this.txtDbUser.Text,
                this.txtDbPwd.Text,
                this.combDb.Text);

            if (DbSvr.TestConnection())
                MessageBox.Show("连接成功");
            else
                MessageBox.Show("连接失败");
        }

        private void btnSelectTabs_Click(object sender, EventArgs e)
        {
            DbSvr = new DbServer(this.combServerAddress.Text,
                this.txtDbUser.Text,
                this.txtDbPwd.Text,
                this.combDb.Text);

            tabControl1.SelectedIndex = 1;
            IList<string> list = DbSvr.GetTableList();
            lstTable.Items.Clear();
            foreach (string name in list)
            {
                lstTable.Items.Add(name);
            }
        }

        private void btnOutPut_Click(object sender, EventArgs e)
        {
            using (FolderBrowserDialog dlg = new FolderBrowserDialog())
            {
                dlg.SelectedPath = txtOutPut.Text;
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    txtOutPut.Text = dlg.SelectedPath;
                }
            }
        }

        private void btnParamsSet_Click(object sender, EventArgs e)
        {
            tabControl1.SelectedIndex = 2;
        }

        private void btnToCreatePage_Click(object sender, EventArgs e)
        {
            tabControl1.SelectedIndex = 3;
        }

        private void btnCreateCode_Click(object sender, EventArgs e)
        {
            #region 验证
            if (string.IsNullOrEmpty(txtAssembly.Text.Trim()))
            {
                MessageBox.Show("程序集不能为空");
                return;
            }
            if (string.IsNullOrEmpty(txtNamespace.Text.Trim()))
            {
                MessageBox.Show("名称空间不能为空");
                return;
            }
            if (string.IsNullOrEmpty(txtOutPut.Text.Trim()))
            {
                MessageBox.Show("请选择输出目录");
                return;
            }
            #endregion

            #region 加载数据表
            IList<string> listTable = new List<string>();
            //装入选择的表
            foreach (object tableName in lstTable.SelectedItems)
            {
                listTable.Add(tableName.ToString());
            }
            #endregion

            #region 为每个表生成对象和配置文件
            foreach (string tabName in listTable)
            {
                textBoxWriter.WriteLine("开始生成：" + tabName);

                #region 生成CS对象
                //获取表的字段信息
                List<TableRow> list = DbSvr.GetTableRowList(tabName);
                List<DataDict> dataDict = DbSvr.GetDataDictList(tabName);
                Regex regex = new Regex("[A-Z]{1}[a-z0-9]*");
                string Tab = "    ";    //Table占位符
                string className = tabName;
                //去除数据库前缀
                if (!string.IsNullOrEmpty(txtCutTablePrefix.Text.Trim()))
                {
                    className = new Regex(string.Format("^{0}", txtCutTablePrefix.Text.Trim()), RegexOptions.IgnoreCase)
                        .Replace(tabName, "");
                }
                className = className.Replace("_", ""); //类名强行去除下划线
                className = className.Substring(0, 1).ToUpper() + className.Substring(1, className.Length - 1); //首字母大写
                //添加类前缀
                if (!string.IsNullOrEmpty(txtClassPrefix.Text.Trim()))
                {
                    className = txtClassPrefix.Text.Trim() + className;
                }
                className = className.Substring(0, 1).ToUpper() + className.Substring(1, className.Length - 1);  //首字母大写

                StringBuilder sb = new StringBuilder()
                    .Append("using System;").Append(Environment.NewLine);
                if (chk60EntityMode.Checked)
                {
                    sb.Append("using Mysoft.Map6.Core.EntityBase;").Append(Environment.NewLine);
                }
                else
                {
                    sb.Append("using Mysoft.Map.Extensions.DAL;").Append(Environment.NewLine);
                }

                //表中文名
                var tableNameC = dataDict.Count() > 0 ? dataDict.First().TableNameC : "无";

                sb.Append(Environment.NewLine)
                .Append("namespace ").Append(txtNamespace.Text).Append(Environment.NewLine)
                .Append("{").Append(Environment.NewLine)
                .Append(Tab).Append("/// <summary>").Append(Environment.NewLine)
                .Append(Tab).Append(string.Format("/// 说明：{0}", tableNameC)).Append(Environment.NewLine)
                .Append(Tab).Append("/// 实体生成器自动生成（杜一博）").Append(Environment.NewLine)
                .Append(Tab).Append("/// 创建人：").Append(txtCreator.Text.Trim()).Append(Environment.NewLine)
                .Append(Tab).Append("/// 创建时间：").Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")).Append(Environment.NewLine)
                .Append(Tab).Append("/// </summary>").Append(Environment.NewLine)
                .Append(Tab).Append("[Serializable]").Append(Environment.NewLine)
                .Append(Tab);

                if (chk60EntityMode.Checked)
                {
                    sb.Append(string.Format("[EntityName(\"{0}\")]", tabName))
                    .Append(Environment.NewLine)
                    .Append(Tab).Append("public abstract class ").Append(className).Append(" : Entity")
                    .Append(Environment.NewLine)
                    .Append(Tab).Append("{").Append(Environment.NewLine);
                }
                else
                {
                    sb.Append(string.Format("[DataEntity(Alias = \"{0}\")]", tabName))
                    .Append(Environment.NewLine)
                    .Append(Tab).Append("public class ").Append(className).Append(" : BaseEntity")
                    .Append(Environment.NewLine)
                    .Append(Tab).Append("{").Append(Environment.NewLine);
                }

                sb.Append(Tab).Append(Tab).Append("#region 属性").Append(Environment.NewLine).Append(Environment.NewLine);

                //生成属性
                foreach (TableRow m in list)
                {
                    if (chk60EntityMode.Checked
                        && new string[] {
                            "CreatedGUID",
                            "CreatedName",
                            "CreatedTime",
                            "ModifiedGUID",
                            "ModifiedName",
                            "ModifiedTime",
                            "VersionNumber"
                        }.Contains(m.ColName))
                    {
                        //忽略系统自带的几个字段
                        continue;
                    }

                    StringBuilder tmp = new StringBuilder();
                    string comment = string.IsNullOrEmpty(m.Comment) ?
                        (dataDict.FirstOrDefault(o => o.FieldName == m.ColName) == null ? string.Empty : dataDict.FirstOrDefault(o => o.FieldName == m.ColName).FieldNameC)
                        : m.Comment;
                    tmp.Append(Tab).Append(Tab).Append("/// <summary>").Append(Environment.NewLine);
                    tmp.Append(Tab).Append(Tab).Append("/// ").Append(comment).Append(Environment.NewLine);
                    tmp.Append(Tab).Append(Tab).Append("/// </summary>").Append(Environment.NewLine);
                    if (chk60EntityMode.Checked)
                    {
                        //[EntityColumn("x_FieldName")]生成
                        if (chkRemoveX.Checked && m.ColName.StartsWith("x_"))
                        {
                            tmp.Append(Tab).Append(Tab);
                            tmp.Append(string.Format("[EntityColumn(\"{0}\")]", m.ColName));
                            tmp.Append(Environment.NewLine);
                        }
                    }
                    else
                    {
                        tmp.Append(Tab).Append(Tab);

                        List<string> DataColumnProperts = new List<string>();
                        //[DataColumn(PrimaryKey = true)]生成
                        if (m.IsPk)
                        {
                            //是否主键
                            DataColumnProperts.Add("PrimaryKey = true");
                        }
                        if (m.IsNull)
                        {
                            //是否可空
                            DataColumnProperts.Add("IsNullable = true");
                        }
                        if (m.IsIdentity)
                        {
                            //是否可空
                            DataColumnProperts.Add("Identity = true");
                        }
                        if (m.ColType.ToString().ToLower() == "timestamp")
                        {
                            DataColumnProperts.Add("TimeStamp = true");
                        }
                        if (m.ColName.IndexOf("_") > 0)
                        {
                            //是否字段名称有下划线
                            DataColumnProperts.Add(string.Format("Alias = \"{0}\"", m.ColName));
                        }
                        if (DataColumnProperts.Count > 0)
                        {
                            tmp.Append(string.Format("[DataColumn({0})]", string.Join(", ", DataColumnProperts.ToArray())));
                        }
                        else
                        {
                            tmp.Append("[DataColumn]");
                        }

                        tmp.Append(Environment.NewLine);
                    }
                    tmp.Append(Tab).Append(Tab).Append("public ");
                    if (chk60EntityMode.Checked)
                    {
                        tmp.Append("virtual ");
                        tmp.Append(DbSvr.GetNetType(m.ColType, m.IsNull)).Append(" ")
                            .Append(chkRemoveX.Checked ? Regex.Replace(m.ColName, "^x_", "") : m.ColName)
                            .Append(" { set; get; }").Append(Environment.NewLine);
                    }
                    else
                    {
                        tmp.Append(DbSvr.GetNetType(m.ColType, m.IsNull)).Append(" ")
                            .Append(string.Join("", m.ColName.Split('_').Select(s => s.Substring(0, 1).ToUpper() + s.Substring(1)).ToArray()))
                            .Append(" { set; get; }").Append(Environment.NewLine);
                    }
                    sb.Append(tmp).Append(Environment.NewLine);
                }
                sb.Append(Tab).Append(Tab)
                    .Append(Environment.NewLine)
                    .Append(Tab).Append(Tab)
                    .Append("#endregion")
                    .Append(Environment.NewLine);

                //结尾反括号
                sb.Append(Environment.NewLine);
                sb.Append(Tab).Append("}").Append(Environment.NewLine); //类反括号
                sb.Append("}"); //名字空间反括号
                #endregion

                #region 保存到文件

                //cs
                File.WriteAllText(string.Format(@"{0}\{1}", txtOutPut.Text, className + ".cs"), sb.ToString(), System.Text.Encoding.Default);

                #endregion
            }
            textBoxWriter.WriteLine("全部完成");
            #endregion

            //打开生成结果目录
            Process.Start(txtOutPut.Text);
        }

        private void combFromRegister_SelectedValueChanged(object sender, EventArgs e)
        {
            string text = (sender as ComboBox).Text;
            if (text == "不从注册表加载")
            {
                return;
            }
            else
            {
                DBInfoModel dbinfo = Code.GetDBInfo(text);
                combServerAddress.Text = dbinfo.Address;
                txtDbUser.Text = dbinfo.UserName;
                txtDbPwd.Text = dbinfo.Passoword == "6.707" ? "95938" : dbinfo.Passoword;
                combDb.Text = dbinfo.DBName;
            }
        }

        //打开目录
        private void txtOutPut_DoubleClick(object sender, EventArgs e)
        {
            try
            {
                Process.Start(txtOutPut.Text);
            }
            catch
            {
                MessageBox.Show("无法打开指定路径", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        #region 异步提示生成内容
        private delegate void ShowProcessor(string message);

        private void CreateProcessor(string message)
        {
            txtLog.AppendText(message + Environment.NewLine);
        }

        #endregion
    }
}